﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;

// This library complies with the OSTA UDF Specification, Revision 1.02, ISO/IEC 
// 13346, and ECMA-167. Where possible, classes have been annotated with where
// they are defined. Reference code is used where possible, adapted as necessary
// for practicality and ease of use in a C# environment.
//
// Copied Right in the year 2012 G.U.E. by Matthew Saunier. Licensed under the
// Lesser GNU Public License, version 2.1 or any later version (at your option) or
// the Microsoft Public License, dated 12 October 2006 or any later version (at 
// your option). Long and short of it is, you can use this code in a closed-source
// application with proper attribution. If you decide to open up your code, you
// must license it under the LGPL, MS-PL, or any license that complies with the
// conditions of either, such as the GPL or the MS-RL.
//
// Note: All UDF data structures are stored little-endian, regardless of the host
// system native byte order. The << and >> operators are arithmetic shift on
// any of the numeric types, so by using them endian conversion must be done every 
// time. BitConverter.IsLittleEndian is currently busted.
//
// Also note: There are bits and pieces in here, mostly in Structs.cs, that are 
// only used with currently-unsupported revisions of UDF. If you're fooling with
// the structs and cursing them for being overwrought, that's probably why.

namespace UdfFactory
{
    public class UdfFactory
    {
        readonly ushort LogicalBlockSize;
        readonly ushort UdfRevision;
        string VolumeName;
        UdfDirectory RootDirectory = new UdfDirectory("/");

        UdfFactory(ushort LogicalBlockSize, ushort UdfRevision)
        {
            if ((LogicalBlockSize % 512) != 0)
                throw new ArgumentException();
            this.LogicalBlockSize = LogicalBlockSize;
            if (UdfRevision != 0x0102) 
                throw new NotImplementedException();
            this.UdfRevision = UdfRevision;
        }

        IRandomAccessStream GenerateWinRTStream() { return ((IRandomAccessStream)GenerateStream()); }
        Stream GenerateStream()
        {
            MemoryStream volumePreamble = new MemoryStream();

            volumePreamble.Write(new byte[32768], 0, 32768);
            volumePreamble.Write(VolumeStructureDescriptor.BeginningExtendedAreaDescriptor(), 32768, 2048);
            if (UdfRevision / 256 == 1)
                volumePreamble.Write(VolumeStructureDescriptor.NonSequentialRecording2Descriptor(), 34816, 2048);
            else
                volumePreamble.Write(VolumeStructureDescriptor.NonSequentialRecording3Descriptor(), 34816, 2048);
            volumePreamble.Write(VolumeStructureDescriptor.TerminatingExtendedAreaDescriptor(), 36864, 2048);
            volumePreamble.Write(new byte[(LogicalBlockSize * 256) - 38912], 38912, (LogicalBlockSize * 256) - 38912);










            return volumePreamble;
        }

    }
}
